package com.wondream.netty.tank.s04;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.ReferenceCountUtil;

public class Client {
	
	private Channel channel = null;
	
	public void connect() {
		//�̳߳�
				EventLoopGroup group = new NioEventLoopGroup(1);
				
				Bootstrap b = new Bootstrap();
				
				try {			
					ChannelFuture f = 
							b.group(group)
						.channel(NioSocketChannel.class)
						.handler(new ClientChannelInitializer())
						.connect("localhost", 8888)
						;
								
					f.addListener(new ChannelFutureListener() {
						@Override
						public void operationComplete(ChannelFuture future) throws Exception {
							if(!future.isSuccess()) {
								System.out.println("not connected!");
							} else {
								System.out.println("connected!");
								//initialize the channel
								channel = future.channel(); 
							}
						}
					});
					
					f.sync();
					//wait until close
					f.channel().closeFuture().sync();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					group.shutdownGracefully();
				}
	}
	
	public static void main(String[] args) throws Exception {
		Client c = new Client();
		c.connect();
	}
}

class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ch.pipeline().addLast(new ClientHandler());
	}
	
}

class ClientHandler extends ChannelInboundHandlerAdapter {

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		ByteBuf buf = null;
		try {
			buf = (ByteBuf)msg;	
			byte[] bytes = new byte[buf.readableBytes()];
			buf.getBytes(buf.readerIndex(), bytes);
			System.out.println(new String(bytes));
			//System.out.println(buf);
			//System.out.println(buf.refCnt());
		} finally {
			if(buf != null) ReferenceCountUtil.release(buf);
			//System.out.println(buf.refCnt());
		}
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		//channle ��һ�����Ͽ��ã�д��һ���ַ��� Direct Memory
		ByteBuf buf = Unpooled.copiedBuffer("hello".getBytes());
		ctx.writeAndFlush(buf);
	}
	
}


